package jp.sourceforge.akjrcp.dropsomething;

import java.io.File;
import java.io.IOException;

import jp.sourceforge.akjrcp.akj_betas.Akj_betasPlugin;
import jp.sourceforge.akjrcp.akj_betas.Messages;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegFLVParser;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUtils;
import jp.sourceforge.akjrcp.ffmpeg.FLVInfomation;
import jp.sourceforge.akjrcp.ui.DirectryBasedExecuterListener;
import jp.sourceforge.akjrcp.ui.FileOverwriteControler;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DefaultFFMpegMonitor implements DirectryBasedExecuterListener{
	public static Log log=LogFactory.getLog(DefaultFFMpegMonitor.class);
	FFMpegDropSomethingTab dropsomethingTab;
	private String keyName;
	private String remainTimeLabel=Messages.getString("dropsomething.remainTime")+" - ";
	private String currentTimeLabel=" "+Messages.getString("dropsomething.currentTime")+" - ";
	private DropsomethingAction afterAction;
	private String totalTimeLabel=" "+Messages.getString("dropsomething.totalTime")+" - ";
	
	
	//TODO support -ss(start) -duration option for progress
	private long editStart;
	private long editDuration;
	
		public DefaultFFMpegMonitor(FFMpegDropSomethingTab dropsomethingTab,String keyName){
			this.dropsomethingTab=dropsomethingTab;
			this.keyName=keyName;
		}
		public void beforeConvert() {
			
		}

		public void afterConvert() {
			dropsomethingTab.setProgress(0);
		}

		public void startConvert(File file) {
			log.info("startConvert:");
			dropsomethingTab.setCenterText("");
			dropsomethingTab.setProgress(0);
			
		
			//set guess size.
			FFMpegFLVParser parser=new FFMpegFLVParser(dropsomethingTab.getFFMpegExecuter().getFfmpegPreference().getFfmpegPath());
			FLVInfomation info=parser.parseFile(file);
			initialProgress(info);
			
			
			//on avisynth how to work?
			dropsomethingTab.setStartTime(System.currentTimeMillis());
		
		}
		
		public void initialProgress(FLVInfomation info){
			long time=(long) (FFMpegUtils.timeToDouble(info.getDuration())*1000);
			if(time==0){
				log.warn("maxtime==0:'"+info.getDuration()+"'");
			}
			dropsomethingTab.setProgressMaxTime(time);
			
		}
		/*
		public void initialProgress(FLVInfomation info){
			int guessSize=FFMpegPreference.toKBytes(info.getDuration(), dropsomethingTab.getFFMpegExecuter().getFfmpegPreference().getVideoBitrate()+dropsomethingTab.getFFMpegExecuter().getFfmpegPreference().getAudioBitrate());
			if(guessSize==0){
			log.warn("guessSize=0 video="+dropsomethingTab.getFFMpegExecuter().getFfmpegPreference().getVideoBitrate()+" audio="+dropsomethingTab.getFFMpegExecuter().getFfmpegPreference().getAudioBitrate());	
			}else{
			log.info("guessSize:"+guessSize);
			}
			dropsomethingTab.setProgressMaxBytes(guessSize*=1.1);//for fix to real situation
		}
		*/

		public void endConvert(File input) {
			long t=System.currentTimeMillis()-dropsomethingTab.getStartTime();
			String timeString=FFMpegUtils.toTimeLabel(t);
			String info="["+keyName+":"+Messages.getString("dropsomething.complete")+"]\r\n";
			info+=Messages.getString("dropsomething.file")+":"+input.getAbsolutePath()+"\r\n";
			info+=Messages.getString("dropsomething.converttime")+":"+timeString+"\r\n";
			info+="####\r\n";
			dropsomethingTab.setProgress(100);
			Akj_betasPlugin.getDefault().getProcessPrinter().printOutput(info);
			
			File output=dropsomethingTab.getFFMpegExecuter().getCurrentOutputFile();
			
			dropsomethingTab.setCenterText("");
			if(afterAction!=null){
				afterAction.exec(input,output);
			}
			
			
		}

		public void faildConvert(File file, String message) {
			String info="["+keyName+":"+Messages.getString("dropsomething.faild")+"]\r\n";
			info+=Messages.getString("dropsomething.file")+":"+file.getAbsolutePath()+"\r\n";
			info+="####\r\n\r\n";
			Akj_betasPlugin.getDefault().getProcessPrinter().printOutput(info);
		}

		public void printProcess(String line) {
			//Akj_betasPlugin.getDefault().
			Akj_betasPlugin.getDefault().getProcessPrinter().printError(line);
			
			if(FFMpegUtils.isProgressString(line)){
				
				progress(line);
				
				updateInfoText();
			}
		}

		public boolean askOverwrite(File output) {
			
			return FileOverwriteControler.askOverwrite(dropsomethingTab.getFileOverWriteControler(),output);
		}
		
		/**
		 * kbyte version.
		 * @param currentTime
		 * @return
		 */
		/*
		public void progress(String line){
			int kbyte=FFMpegUtils.getProgressSize(line);
			dropsomethingTab.setProgressKBytes(kbyte);
			dropsomethingTab.progressBytes(kbyte);//progress bar work,call setProgress
		}
		public long getTotalTime(long currentTime){
			int progressMaxBytes=dropsomethingTab.getProgressMaxBytes();
			if(progressMaxBytes==0){
				log.warn("progressMaxBytes 0 ");
				return 0;
			}
			
			long totalTime=0;
			if(dropsomethingTab.getProgressKBytes()>0){
				double ratio=(double)progressMaxBytes/dropsomethingTab.getProgressKBytes();
				totalTime=(long)(currentTime*ratio);
			}
			return totalTime;
		}*/
		
		public void progress(String line){
			long time=FFMpegUtils.getProgressTime(line);
			dropsomethingTab.setProgressTime(time);
			dropsomethingTab.progressTime(time);//
		}
		public long getTotalTime(long currentTime){
			if(currentTime>0){
			//TODO remove
			//	return 0;
			}
			
			long progressMaxTime=dropsomethingTab.getProgressMaxTime();
			if(progressMaxTime==0){
				log.warn("progressMaxBytes 0 ");
				return 0;
			}
			
			long totalTime=0;
			if(dropsomethingTab.getProgressTime()>0){
				double ratio=(double)progressMaxTime/dropsomethingTab.getProgressTime();
				totalTime=(long)(currentTime*ratio);
			}
			return totalTime;
		}
		
		public void updateInfoText(){
			StringBuffer text=new StringBuffer();
			long currentTime=System.currentTimeMillis()-dropsomethingTab.getStartTime();
			long totalTime=getTotalTime(currentTime);
			if(totalTime!=0){
				text.append(remainTimeLabel);
				text.append(FFMpegUtils.toTimeLabel(totalTime-currentTime));
				text.append(currentTimeLabel);
				text.append(FFMpegUtils.toTimeLabel(currentTime));
				text.append(totalTimeLabel);
				text.append(FFMpegUtils.toTimeLabel(totalTime));
				dropsomethingTab.setCenterText(text.toString());
			}else{
				log.warn("totaltime 0 ");
			}
			
		}
		public DropsomethingAction getAfterAction() {
			return afterAction;
		}
		public void setAfterAction(DropsomethingAction afterAction) {
			this.afterAction = afterAction;
		}
		
	}
